﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Text.RegularExpressions;
using HtmlAgilityPack;
using WebBrowserTest.Utility;

namespace WebBrowserTest.DetailsAnalyzing
{
    public class BacklinkDetailsAnalyzer
    {
        private List<BacklinkDetailsSource> _source;
        private string _analyzedDomain = string.Empty;
        private BacklinkDetailsAnalyzer()
        {
        }
        public BacklinkDetailsAnalyzer(BacklinkDetailTO source)
        {
            _source = source.Sources;
            _analyzedDomain = source.AnalyzedDomain;
        }

        private int PageRankSum()
        {
            return _source.Select(o => o.MainAnalyzeResult).Sum(o => o.PageRank);
        }
        
        private DomainCountResult UniqueDomains(DetailsProgressItems dpItems)
        {
            DomainCountResult countResult = new DomainCountResult();
            int uniqueDomainsCount = 0;
            int uniqueMainDomains = 0;
            int uniqueIpAddressCount = 0;
            int totalAnchors = 0;
            int uniqueAnchors = 0;
            int notFollowLinkCount = 0;
            int followLinkCount = 0;
            int polishDomainCount = 0;
            List<string> anchorValues = new List<string>();
         


            dpItems.SetMaxProgressValue(_source.Count);
            List<string> urls = _source.Select(o => o.Domain).ToList();
            List<string> mainDomains = new List<string>();
            foreach (var url in urls)
            {
                mainDomains.Add(Utils.ExtractDomainNameFromUR(url));
            }

            //unique domains
            uniqueDomainsCount = urls.Distinct().Count();
            
            //unique mainDomains
            uniqueMainDomains = mainDomains.Distinct().Count();
           

            //unique ips
            List<string> ipList = new List<string>();
            foreach (var domain in mainDomains)
            {
                IPAddress[] ip = null;
                try
                {
                    ip = Dns.GetHostAddresses(domain);
                }
                catch (Exception)
                {

                }
                if (ip != null) ipList.Add(ip[0].ToString());
            }
            uniqueIpAddressCount = ipList.Distinct().Count();

            
            foreach (var detailsSource in _source)
            {
                var anchors = detailsSource.HtmlDocument.DocumentNode.SelectNodes("//a");
                if(anchors == null) continue;

                anchorValues.AddRange(anchors.Where(o => o.Attributes["href"]!= null &&
                                                   o.Attributes["href"].Value !=null &&
                                                         o.Attributes["href"].Value.ToLower().Contains(
                                                             _analyzedDomain.ToLower())).Select(
                                                                 x => x.InnerText.ToLower().Trim()).ToList());
                                          
             


                //follow not follow
                var anchorRelAttr =
                   anchors.Select(
                       o => o.Attributes["rel"] == null ? "" : o.Attributes["rel"].Value).ToList();
                anchorRelAttr.RemoveAll(o => o == string.Empty);
                foreach (var relAttribute in anchorRelAttr)
                {
                    if (relAttribute.ToLower().Trim() == "nofollow")
                    {
                        notFollowLinkCount++;
                    }
                    if (relAttribute.ToLower().Trim() == "follow")
                    {
                        followLinkCount++;
                    }
                }
                #region old code
                //var notUniqueDomainsAnchors = anchors.Select(o => o.Attributes["href"] == null ? "" : o.Attributes["href"].Value ?? "").ToList();

                //var relAttributes =
                //    detailsSource.HtmlDocument.DocumentNode.SelectNodes("//a").Select(
                //        o => o.Attributes["rel"] == null ? "" : o.Attributes["rel"].Value).ToList();
                //relAttributes.RemoveAll(o => o == string.Empty);
                //foreach (var relAttribute in relAttributes)
                //{
                //    if (relAttribute.ToLower().Trim() == "nofollow")
                //    {
                //        notFollowLinkCount++;
                //    }
                //    if (relAttribute.ToLower().Trim() == "follow")
                //    {
                //        followLinkCount++;
                //    }
                //}

                //var uniqueDomains = notUniqueDomainsAnchors.Distinct();
                //uniqueDomains.ToList().RemoveAll(o => (!o.StartsWith("http://") || !o.StartsWith("www.")));
                //notUniqueDomainsAnchors.ToList().RemoveAll(o => (!o.StartsWith("http://") || !o.StartsWith("www.")));

                //polishDomainCount += uniqueDomains.Where(o => o.EndsWith(".pl")).Count();

                //totalAnchors += notUniqueDomainsAnchors.Count;
                //uniqueAnchors += uniqueDomains.Count();

                //List<string> mainDomainsList = new List<string>();
                //List<string> uniqueIp = new List<string>();

                //foreach (var uniqueDomain in uniqueDomains)
                //{
                //    var d = uniqueDomain;
                //    if (!d.StartsWith("http://"))
                //    {
                //        d = string.Format("http://{0}", uniqueDomain);
                //    }
                //    string host = string.Empty;

                //    try
                //    {
                //        host = new Uri(d).Host;
                //    }
                //    catch (UriFormatException)
                //    {

                //    }
                //    if (host != string.Empty && !mainDomainsList.Contains(host))
                //    {
                //        mainDomainsList.Add(host);
                //        IPAddress[] ipList = null;
                //        try
                //        {
                //            ipList = Dns.GetHostAddresses(host);
                //        }
                //        catch (Exception)
                //        {

                //        }
                //        if (ipList != null && ipList.Count() > 0)
                //        {

                //            string ip = ipList[0].ToString();
                //            if (!uniqueIp.Contains(ip))
                //            {
                //                uniqueIp.Add(ip);
                //            }

                //        }
                //    }

                //    //unique IP




                //    //follow/notfollow

                //}
                //uniqueMainDomains += mainDomainsList.Count;
                //uniqueDomainsCount += uniqueDomains.Count();
                //uniqueIpAddressCount += uniqueIp.Count; 
                #endregion
                dpItems.UpdateProgress(1);
            }
            totalAnchors = anchorValues.Count;
            uniqueAnchors = anchorValues.Distinct().Count();
            polishDomainCount = _source.Where(o => o.Domain.ToLower().Contains(".pl")).Count();
            countResult.UniqueDomains = uniqueDomainsCount;
            countResult.UniqueMainDomains = uniqueMainDomains;
            countResult.DifferentAnchors = ((float) uniqueAnchors/totalAnchors)*100;
            countResult.LinkFollow = followLinkCount;
            countResult.LinkNotFollow = notFollowLinkCount;
            countResult.UniqueIp = uniqueIpAddressCount;
            countResult.PolishDomains = polishDomainCount;
            return countResult;
        }

        public AnalyzeDetails GetBackLinkAnalyzeDatails(DetailsProgressItems dpItems)
        {
            AnalyzeDetails analyzeDetails = new AnalyzeDetails();

            //page rank sum
            analyzeDetails.PageRankSum = PageRankSum();
            dpItems.UpdateProgress(1);
            //unique domains
            int mainDomainsCount = 0;
            var uniqDomainsCountResult = UniqueDomains(dpItems);

            analyzeDetails.UniqueDomains = uniqDomainsCountResult.UniqueDomains;
            analyzeDetails.UniqueMainDomains = uniqDomainsCountResult.UniqueMainDomains;
            analyzeDetails.LinkFollow = uniqDomainsCountResult.LinkFollow;
            analyzeDetails.LinkNotFollow = uniqDomainsCountResult.LinkNotFollow;
            analyzeDetails.UniqueIp = uniqDomainsCountResult.UniqueIp;
            analyzeDetails.AnchorDiff = uniqDomainsCountResult.DifferentAnchors;
            analyzeDetails.Density = _source.Select(o => o.MainAnalyzeResult).Average(x => x.Density);
            analyzeDetails.PolishDomains = uniqDomainsCountResult.PolishDomains;
            ((CEOTool) dpItems.MainForm).DisplayDetailsAnalyzeResults(analyzeDetails);
            return analyzeDetails;
            
        }
        
    }
    public class DomainCountResult
    {
        public int UniqueDomains { get; set; }

        public int UniqueMainDomains { get; set; }

        public float DifferentAnchors { get; set; }

        public int UniqueIp { get; set; }

        public int LinkFollow { get; set; }

        public int LinkNotFollow { get; set; }

        public int PolishDomains { get; set; }
    }
}
